<script setup lang="ts">
import { ref, watch, computed, onUnmounted, onBeforeUnmount, onMounted } from 'vue'
import { ElMessageBox as Modal, ElNotification as notification } from 'element-plus'
import { Fold, Expand } from '@element-plus/icons-vue'
import logo from '@/assets/logo.png'
import leftMenu from '@/layouts/components/menu/myMenu.vue'
import navTag from './components/navTag/navTag.vue'
import selectLang from './components/selectLang/selectLang.vue'
import { useUserStore, useNavTagsStore } from '@/store'
import { useRoute } from 'vue-router'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
import eventBus from '@/common/eventBus'
import wsl3 from '@/assets/imgs/wsl3.webp'
import { sysLayoutName } from '@/router/config'
import { layoutConfig } from '@/common/config'

const navTagsStore = useNavTagsStore()
const userStore = useUserStore()
const route = useRoute()

const {
	gap,
	showWelcome,
	initMenuWidth,
	menuWidth_collapsed,
	menuCollapsedScreenWidthPoint,
	menuTheme,
	menuTextColor,
	topBarHeight,
	navTagContainerHeigth,
	bottomBarHeight,
	transitionTime,
	barBgColor,
} = layoutConfig

const menuWidth = ref(initMenuWidth)
const menuRef = ref<InstanceType<typeof leftMenu> | null>()
const collapse = ref(false)
const isRightTransition = ref(true)
const noCachePages = ref(new Set<string>([]))
const breadcrumbList = ref<{ title: string; [key: string]: any }[]>([])

eventBus.on('sendInfoToLayout', (msg: any) => {
	console.log(msg)
})
onUnmounted(() => {
	eventBus.off('*')
})

onMounted(() => {
	if (showWelcome)
		notification({
			type: 'success',
			title: '欢迎',
			message: `欢迎${userStore.info.username}来到本系统`,
			duration: 2000,
		})
})

const handleNavTagChange = (newRoute: RouteLocationNormalizedLoaded) => {
	if (!newRoute.meta.noKeepAlive) {
		const tags = navTagsStore.tags
		const index = tags.findIndex((v) => v.name === newRoute.name)
		// console.log(index)
		if (index !== -1) {
			navTagsStore.activeTag({ index, fullPath: newRoute.fullPath })
		} else {
			const { title, affix } = route.meta
			const { fullPath, name } = route
			navTagsStore.addTag({ name, title, fullPath, affix: affix ? true : false } as any)
		}
	} else navTagsStore.clearActive()
}

const handleMenuActive = (newRoute: RouteLocationNormalizedLoaded) => {
	const activePath = newRoute.matched.map((v) => v.name)
	menuRef.value?.changeActive(newRoute.name as string, activePath as string[])
}

// 非缓存页设置。需要注意的是：要使得非缓存生效，非缓存页组件需要写name属性，且name属性的值要与路由配置的name属性值一致
const setNoCachePage = (newRoute: RouteLocationNormalizedLoaded) => {
	if (newRoute.meta.noKeepAlive) noCachePages.value.add(newRoute.name as string)
	// console.log(noCachePages.value)
}

const handleBreadcrumb = (newRoute: RouteLocationNormalizedLoaded) => {
	breadcrumbList.value = newRoute.matched
		.map((v: any) => {
			return {
				name: v.name,
				title: v.meta.title,
				path: v.path,
			}
		})
		.filter((v: any) => v.name != sysLayoutName)
}

watch(
	route,
	(newRoute, _oldRoute) => {
		//console.log('watch route',{...route})
		handleNavTagChange(newRoute)
		handleMenuActive(newRoute)
		handleBreadcrumb(newRoute)
		setNoCachePage(newRoute)
	},
	{ immediate: true }
)

const isNeedLayout = computed(() => {
	return !route.meta.hiddenLayout
})

const isNeedMenu = computed(() => {
	return !route.meta.hiddenMenu && isNeedLayout.value
})

watch(
	isNeedMenu,
	(newV, _oldV) => {
		//console.log("isRightTransition",newV)
		if (newV)
			setTimeout(() => {
				isRightTransition.value = true
			}, 500)
		else isRightTransition.value = false
	},
	{ immediate: true }
)

watch(collapse, (n) => {
	if (n) menuWidth.value = menuWidth_collapsed
	else menuWidth.value = initMenuWidth
})

const logout = () => {
	Modal.confirm('确定要退出登录吗?', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		draggable: true,
		// type: 'warning',
		beforeClose: async (action, instance, done) => {
			if (action === 'confirm') {
				instance.confirmButtonLoading = true
				await userStore.logout(route.fullPath)
				instance.confirmButtonLoading = false
				done()
			} else {
				done()
			}
		},
	})
		.then(() => {})
		.catch(() => {})
}

const windowResize = () => {
	if (isNeedMenu) {
		if (document.documentElement.clientWidth <= menuCollapsedScreenWidthPoint) {
			collapse.value = true
		} else {
			collapse.value = false
		}
	}
}

window.addEventListener('resize', windowResize)
onBeforeUnmount(() => {
	window.removeEventListener('resize', windowResize)
})

onMounted(() => {
	// console.log(document.documentElement.clientWidth)
	if (isNeedMenu && document.documentElement.clientWidth <= menuCollapsedScreenWidthPoint) {
		collapse.value = true
	}
})
</script>
<template>
	<div class="BasicLayout">
		<div class="layout-left" v-show="isNeedMenu" :style="{ width: menuWidth + 'px', transition: `width ${transitionTime}` }">
			<el-scrollbar>
				<h1 class="logo">
					<img :src="logo" alt="sysLogo" />
				</h1>
				<div class="layout-menu">
					<leftMenu ref="menuRef" :collapse="collapse" :width="initMenuWidth + 'px'" :collapse-width="menuWidth_collapsed + 'px'" :theme="menuTheme" :textColor="menuTextColor" />
				</div>
			</el-scrollbar>
		</div>

		<div class="layout-rigth" :style="{ paddingLeft: isNeedMenu ? menuWidth + 'px' : 0, transition: isRightTransition ? `padding-left ${transitionTime}` : 'none' }">
			<div class="layout-rigth-header" v-show="isNeedLayout">
				<div class="header-left" @click="collapse = !collapse">
					<div style="cursor: pointer; display: flex" class="collapse-icon" v-show="isNeedMenu">
						<el-icon :size="20" color="white" v-show="!collapse"><Fold /></el-icon>
						<el-icon :size="20" color="white" v-show="collapse"><Expand /></el-icon>
					</div>
					<div class="breadcrumb" style="margin-left: 10px">
						<el-breadcrumb separator="/">
							<el-breadcrumb-item v-for="item in breadcrumbList" :key="item.name">
								<span style="color: white">{{ item.title }}</span>
							</el-breadcrumb-item>
						</el-breadcrumb>
					</div>
				</div>

				<div class="header-right">
					<div class="selectLang-container" style="margin-right: 22px">
						<selectLang />
					</div>
					<el-dropdown>
						<div class="avatar-container" style="display: flex; align-items: center; outline: none">
							<el-avatar shape="square" :size="36" :src="userStore.info.avatar ? userStore.info.avatar : wsl3" />
							<!-- <el-icon  :size="15" color="white" >
						<arrow-down />
						</el-icon> -->
						</div>
						<template #dropdown>
							<el-dropdown-menu>
								<el-dropdown-item @click="logout">退出登录</el-dropdown-item>
								<el-dropdown-item
									@click="
										() => {
											$window.open('https://blog.csdn.net/qq_61233877/article/details/131008600?spm=1001.2014.3001.5502')
										}
									"
									>项目描述</el-dropdown-item
								>
							</el-dropdown-menu>
						</template>
					</el-dropdown>
				</div>
			</div>
			<div class="fast-navTag-container" v-show="isNeedLayout">
				<navTag />
			</div>
			<div class="layout-rigth-main" :style="{ padding: isNeedLayout ? '' : 0, width: isNeedLayout ? '' : 'auto' }">
				<div class="content" :style="{ backgroundColor: isNeedLayout ? '' : 'unset' }">
					<Suspense>
						<template #default>
							<router-view v-slot="{ Component }">
								<transition mode="out-in" name="page" appear>
									<KeepAlive :exclude="[...noCachePages]">
										<component :is="Component" />
									</KeepAlive>
								</transition>
							</router-view>
						</template>
						<template #fallback>
							<div v-loading="false" class="loadingPage" element-loading-text="数据加载中..."></div>
						</template>
					</Suspense>
				</div>
			</div>
			<div class="layout-right-footer" v-show="isNeedLayout && parseInt(bottomBarHeight)">
				<p class="txt">
					copyright &copy;
					<el-link style="margin-left: 3px" type="primary" target="_blank" :underline="false" href="https://gitee.com/gitee_lw/projects?sort=&scope=&state=public">lw</el-link>
				</p>
			</div>
		</div>

		<el-backtop :right="50" :bottom="100" />
	</div>
</template>

<style lang="scss" scoped>
.BasicLayout {
	width: 100%;

	.layout-left {
		position: fixed;
		top: 0;
		bottom: 0;
		background-color: v-bind(menuTheme);
		// overflow: auto;
		z-index: 999;

		.logo {
			height: 32px;
			margin: 16px 16px 25px;
			text-align: center;

			img {
				height: 42px;
				width: 42px;
			}
		}

		.layout-menu {
			width: 100%;
			display: flex;
			justify-content: center;
		}
	}

	.layout-rigth {
		min-height: 100vh;
		box-sizing: border-box;
		background-color: #f0f2f5;

		.layout-rigth-header {
			position: sticky;
			top: 0;
			z-index: 99;
			height: v-bind(topBarHeight);
			background-color: v-bind(barBgColor);
			display: flex;
			align-items: center;
			justify-content: space-between;
			user-select: none;

			.header-left {
				height: 100%;
				margin-left: v-bind(gap);
				display: flex;
				align-items: center;
				:deep(.el-breadcrumb__separator) {
					color: white;
				}
			}

			.header-right {
				margin-right: 20px;
				display: flex;
				height: 100%;
				align-items: center;

				:deep(.el-dropdown .el-dropdown-link) {
					outline: none;
				}

				.title {
					font-size: 14px;
					color: #a9a8ae;
					margin: 0 20px;
				}
			}
		}

		.fast-navTag-container {
			height: v-bind(navTagContainerHeigth);
			background-color: white;
			position: sticky;
			top: v-bind(topBarHeight);
			z-index: 99;
		}

		.layout-rigth-main {
			position: relative;
			box-sizing: border-box;
			padding: v-bind(gap);

			.content {
				overflow: hidden;
				box-sizing: border-box;
				min-height: calc(100vh - v-bind(topBarHeight) - v-bind(navTagContainerHeigth) - v-bind(bottomBarHeight) - calc(v-bind(gap) * 2));
				padding: v-bind(gap);
				background-color: white;
			}
			.loadingPage {
				width: 300px;
				height: 300px;
				position: absolute;
				left: 50%;
				top: 50%;
				transform: translate(-50%, -50%);
				z-index: 999;
			}
		}

		.layout-right-footer {
			width: 100%;
			height: v-bind(bottomBarHeight);
			background-color: v-bind(barBgColor);
			display: flex;
			align-items: center;

			.txt {
				width: 100%;
				height: 30px;
				color: #a9a8ae;
				margin: 0;
				font-size: 14px;
				display: flex;
				justify-content: center;
				align-items: center;
			}
		}
	}
}
</style>
